<?php

namespace StudyBuddy\Controllers;

use \StudyBuddy\Responder;
use \StudyBuddy\WebPage;
use \StudyBuddy\Answer;
use \StudyBuddy\Question;
use \StudyBuddy\Request;
use \StudyBuddy\Mailer;

/**
 * Controller for processing the
 * "Flag item as inappropriate"
 *
 */
class Flagger extends WebPage
{

	/**
	 * Template of report email
	 *
	 * @todo translate string
	 *
	 * @var string
	 */
	protected $EMAIL_BODY = '
	User: %1$s
	Profile: %2$s
	
	Reported this %3$s
	%4$s
	
	Message body: %5$s
	
	Reason: %6$s
	
	Note: %7$s
	
	';

	protected $SUBJECT = 'Flagged item';

	const TIME_PERIOD = 86400;

	const MAX_FLAGS = 10;

	protected $membersOnly = true;

	protected $requireToken = true;

	protected $aRequired = array('rid', 'rtype');

	protected $oResource;

	/**
	 * Name of collection
	 * Usually QUESTIONS or ANSWERS
	 *
	 * @var string
	 */
	protected $collection;


	protected function main(){
		$this->collection = ('q' == $this->oRequest['rtype']) ? 'QUESTIONS' : 'ANSWERS';
		$this->checkReportFlood()
		->getResource()
		->updateResource()
		->logReport()
		->notifyModerators()
		->returnResult();
	}


	/**
	 * Create object of type Question or Answer
	 *
	 * @return object $this
	 */
	protected function getResource(){

		d('type: '.$this->collection);
		$coll = $this->oRegistry->Mongo->getCollection($this->collection);
		$a = $coll->findOne(array('_id' => (int)$this->oRequest['rid']));
		d('a: '.print_r($a, 1));

		if(empty($a)){
				
			throw new \StudyBuddy\Exception('Item not found');
		}

		$class = ('QUESTIONS' === $this->collection) ? '\\StudyBuddy\\Question' : '\\StudyBuddy\\Answer';

		$this->oResource = new $class($this->oRegistry, $a);

		return $this;
	}


	/**
	 * Increase count of flags for this item
	 *
	 * @return object $this
	 */
	protected function updateResource(){
		$coll = $this->oRegistry->Mongo->getCollection($this->collection);
		$coll->update(array("_id" => (int)$this->oRequest['rid']), array('$inc' => array("i_flags" => 1)), array("fsync" => true));

		return $this;
	}


	/**
	 * Check that user is not abusing "Flag"
	 * option
	 * Maximum allowed uses is 5 in 24 hours
	 * but this does not apply to moderator
	 *
	 * @throws \StudyBuddy\Exception
	 */
	protected function checkReportFlood(){
		$oViewer = $this->oRegistry->Viewer;
		if(!$oViewer->isModerator()){

			$since = time() - self::TIME_PERIOD; // 24 hours
			$cur = $this->oRegistry->Mongo->REPORTED_ITEMS
			->find(array('i_uid' => $this->oRegistry->Viewer->getUid(), 'i_ts' => array('$gt' => $since)), array('i_ts', 'hts'));

			if($cur && ($cur->count(true) > self::MAX_FLAGS) ){

				throw new \StudyBuddy\Exception('You have reached the limit of '.self::MAX_FLAGS.' reports in 24 hours');
			}
		}

		return $this;
	}


	/**
	 * Insert this flag report into FLAGGED_ITEMS collection
	 *
	 * Enter description here ...
	 */
	protected function logReport(){
		$data = array(
		'i_ts' => time(),
		'h_ts' => date('r'),
		'i_res' => $this->oRequest['rid'],
		'i_qid' => $this->oRequest['qid'],
		'rtype' => $this->oRequest['rtype'],
		'i_uid' => $this->oRegistry->Viewer->getUid(),
		'username' => $this->oRegistry->Viewer->getDisplayName(),
		'note' => $this->oRequest->getUTF8('note')->stripTags()->valueOf()
		);

		$coll = $this->oRegistry->Mongo->REPORTED_ITEMS;
		$coll->ensureIndex(array('i_uid' => 1));

		$coll->insert($data);
		
		$this->makeActionCount('report_abuse_total'); //hoangto

		return $this;
	}
	
	//hoangto make action count
	function makeActionCount($countType = ''){
	
		$coll = $this->oRegistry->Mongo->ACTIONCOUNT;
	
		$count = $coll->findOne(array('i_uid' => $this->oRegistry->Viewer->getUid()), array('_id',$countType));
		
		if(empty($count[$countType])){
			$total = 1;
		}else{
			$total = (int)$count[$countType] + 1;
		}
			
		if(empty($count['_id'])){
			$countData = array(
				'i_uid' => $this->oRegistry->Viewer->getUid(),
				$countType => $total
			);
			$this->oRegistry->Mongo->ACTIONCOUNT->insert($countData);
		}else{
			$countData = array(
				'$set' => array($countType => $total)
			);
			$this->oRegistry->Mongo->ACTIONCOUNT->update(array('i_uid' => $this->oRegistry->Viewer->getUid()),$countData);
		}
		
		$coll->ensureIndex(array('i_uid' => 1));
		
		$this->checkGainBadges($countType, $this->oRegistry->Viewer->getUid());
		
		return $this;
	}

	//hoangto
	protected function checkGainBadges($countType, $uid){
		
		$count = $this->oRegistry->Mongo->ACTIONCOUNT->findOne(array('i_uid' => $uid), array($countType));
		$cond = $this->oRegistry->Mongo->BADGES->find(array('cond_type' => $countType, 'cond' => array('$lte' => $count[$countType])));
		
		foreach($cond as $obj){
			$actData = array(
				'i_uid' => $uid,
				'username' => $this->oRegistry->Viewer->getDisplayName(),
				'i_bid' => $obj['id'],
				'badges' => $obj['b_name'],
				'badges_type' => $obj['type']
			);
			$isExist = $this->oRegistry->Mongo->USER_BADGES->findOne($actData);
			if(empty($isExist)){
				$this->oRegistry->Mongo->USER_BADGES->insert($actData);
				$this->makeActivities('badges', 'earned a badges', $obj['id']);
			}
			$this->oRegistry->Mongo->USER_BADGES->ensureIndex(array('i_uid' => 1));
			$this->oRegistry->Mongo->USER_BADGES->ensureIndex(array('badges' => 1));
		}
		
		return $this;
	}
	
	//hoangto make answer activity
	protected function makeActivities($act_type = 'a', $act_name = 'answered a question', $act_id) {
		$actData = array(
			'i_uid' => $this->oRegistry->Viewer->getUid(),
			'username' => $this->oRegistry->Viewer->getDisplayName(),
			'avt' => $this->oRegistry->Viewer->getAvatarSrc(),
			'act_type' => $act_type,
			'act_id' => $act_id,
			'act_name' => $act_name,
			'i_ts' => time(),
			'hts' => date('F j, Y g:i a T')
		);
	
		$coll = $this->oRegistry->Mongo->ACTIVITIES;
		$coll->ensureIndex(array('i_uid' => 1));
		$coll->ensureIndex(array('i_ts' => 1));
		
		$oActivity = \StudyBuddy\MongoDoc::factory($this->oRegistry, 'ACTIVITIES', $actData);
		$res = $oActivity->save($actData);
		
		return $this;
	}

	/**
	 * Make body of email
	 * using template self::EMAIL_BODY
	 *
	 * @return string body of email to be sent to moderators
	 */
	protected function makeBody(){
		$vars = array(
		$this->oRegistry->Viewer->getDisplayName(),
		$this->oRegistry->Ini->SITE_URL.$this->oRegistry->Viewer->getProfileUrl(),
		('q' == $this->oRequest['rtype']) ? 'Question' : 'Answer',
		$this->oResource->getUrl(),
		$this->oResource['b'],
		$this->oRequest->get('reason', 's', 'not given'),
		$this->oRequest['note']
		);

		d('vars: '.print_r($vars, 1));

		$body = vsprintf($this->EMAIL_BODY, $vars);

		d('body '.$body);

		return $body;
	}


	/**
	 *
	 * Send out emails to all moderators
	 *
	 * @return object $this
	 */
	protected function notifyModerators(){

		$cur = $this->oRegistry->Mongo->USERS->find(array(
  			'role' => array('$in' => array('moderator', 'administrator'))
		), array('email'));

		d('found '.$cur->count().' moderators');

		if($cur && $cur->count() > 0){
			$Mailer = Mailer::factory($this->oRegistry);
			$subject = $this->SUBJECT;
			$body = $this->makeBody();
			$aTo = array();
			foreach($cur as $row){
				$aTo[] = $row['email'];
			}
			
			d('aTo: '.print_r($aTo, 1));
			$Mailer->mail($aTo, $subject, $body);
		}

		return $this;

	}


	protected function returnResult(){
		/**
		 * @todo translate string
		 */
		$message = 'Thank you for caring!<br>Moderators have been notified';
		if(Request::isAjax()){
			Responder::sendJSON(array('alert' => $message));
		}

		Responder::redirectToPage($this->oResource->getUrl());
	}

}
